﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace NpcFramework.Traffic
{
    public enum TrafficLightStatus
    {
        Green = 1,
        Red = 2,
    }
    
    public class TrafficLight : MonoBehaviour
    {
        [System.Serializable]
        public class WaitPointMap
        {
            public int WayPathID;
            public int PointIndex;
            public NpcWayPoint WayPoint;
            public List<TrafficNpcWaitPoint> NpcWaitPoints = new List<TrafficNpcWaitPoint>();
        }

        [System.Serializable]
        public class InnerPointMap
        {
            public int WayPathID;
            public int PointIndex;
            public NpcWayPoint WayPoint;
        }

        public int trafficLightID;

        public TrafficLightStatus LightStatus = TrafficLightStatus.Green;
        // 绿灯时间
        public float greenTime = 12f;
        // 绿灯延迟时间，行人需要等待后才能行走
        public float greenDelayTime = 2f;
        
        // 红灯时间
        public float redTime = 8f;
        // 红灯延迟时间，车辆需等待后才可行走
        public float redDelayTime = 6f;
        
        // 绿灯用于阻挡车辆的碰撞体
        public List<BoxCollider> greenCollider;

        // 用于阻挡行人，防止穿透
        public List<BoxCollider> redCollider;
        
        // 行人通过人行道之前的点，两侧的点与其对应得等待点位
        public List<WaitPointMap> waitPointMaps;
        
        // 在红绿灯内部的路点
        public List<InnerPointMap> innerPointMaps;
        
        // 用于人行道上是否有行人和车辆
        //public ColliderCounter colliderCounter;


        private TrafficManager _trafficManager;
        private bool isInited = false;
        // 绿灯剩余时间
        private float lastTime;
        
        public void OnInit(TrafficManager trafficManager)
        {
            _trafficManager = trafficManager;
            // 默认开始为绿灯
            LightStatus = TrafficLightStatus.Green;
            lastTime = greenTime + redDelayTime;
            SwitchGreenCollider(true);
            SwitchRedCollider(false);

            isInited = true;

            //colliderCounter.onColliderEnter += OnColliderEnter;
            //colliderCounter.onColliderExit += OnColliderExit;
        }
        
        private void OnColliderEnter(Collider obj)
        {
            TrafficCar trafficCar;
            if (TrafficCar.Col2TrafficCarMap.TryGetValue(obj,out trafficCar))
            {
                trafficCar.SwitchBlockCast(false);
            }
            
        }

        private void OnColliderExit(Collider obj)
        {

            TrafficCar trafficCar;
            if (TrafficCar.Col2TrafficCarMap.TryGetValue(obj,out trafficCar))
            {
                trafficCar.SwitchBlockCast(true);
            }
        }



        private void Update()
        {
            // if (!isInited)
            // {
            //     return;
            // }
            //
            // lastTime -= Time.deltaTime;
            //
            // if (LightStatus == TrafficLightStatus.Red)
            // {
            //     if (lastTime < greenDelayTime && lastTime > 0)
            //     {
            //         // 车辆不能走了
            //         SwitchGreenCollider(true);
            //
            //     }
            //     else if(lastTime < 0 && (colliderCounter.CCount == 0 || lastTime < -40f))        // lastTime < -x秒 防止卡死
            //     {
            //         SwitchRedCollider(false);
            //         LightStatus = TrafficLightStatus.Green;
            //         lastTime = greenTime + redDelayTime;
            //         // 通知行人可以走了
            //         _trafficManager.OnTrafficGreen(trafficLightID);
            //     }
            // }
            // else if (LightStatus == TrafficLightStatus.Green)
            // {
            //     if ( lastTime < redDelayTime && lastTime > 0)
            //     {
            //         SwitchRedCollider(true);
            //         
            //         // 通知行人不能过马路了
            //         _trafficManager.OnTrafficRed(trafficLightID);
            //         // TODO 在人行道的行人需要加快速度
            //         
            //         
            //     }
            //     else if (lastTime < 0 && (colliderCounter.CCount == 0 || lastTime < -50f))
            //     {
            //         // 切到红灯，车辆可以走了
            //         SwitchGreenCollider(false);
            //         LightStatus = TrafficLightStatus.Red;
            //         lastTime = redTime + greenDelayTime;
            //     }
            //     
            // }

        }


        private void SwitchGreenCollider(bool enable)
        {
            if (greenCollider!=null)
            {
                foreach (var boxCollider in greenCollider)
                {
                    boxCollider.enabled = enable;
                }
            }
        }


        private void SwitchRedCollider(bool enable)
        {
            if (redCollider!=null)
            {
                foreach (var boxCollider in redCollider)
                {
                    boxCollider.enabled = enable;
                }
            }
        }
        

#if UNITY_EDITOR
        private Transform waitPointParent;
        
        public void RemovePointMap(NpcWayPoint point)
        {
            for (int i = 0; i < waitPointMaps.Count; i++)
            {
                var pointMap = waitPointMaps[i];
                if (pointMap.WayPoint == point)
                {
                    RemoveAllWaitPoint(i);
                    waitPointMaps.Remove(pointMap);
                    break;
                }
            }
        }
        
        public void AddWaitPoint(int i)
        {
            if (waitPointParent == null)
            {
                waitPointParent = transform.Find("waitPoints");
                if (waitPointParent==null)
                {
                    waitPointParent = new GameObject("waitPoints").transform;
                    waitPointParent.parent = this.transform;
                }
            }
            Vector3 pos = waitPointMaps[i].WayPoint.transform.position;

            GameObject obj = new GameObject(waitPointMaps[i].NpcWaitPoints.Count.ToString());
            obj.transform.position = pos + new Vector3(0.3f, 0, 0.3f);
            obj.transform.parent = waitPointParent;
            TrafficNpcWaitPoint npcWaitPoint = obj.AddComponent<TrafficNpcWaitPoint>();
            waitPointMaps[i].NpcWaitPoints.Add(npcWaitPoint);

            Selection.activeGameObject = obj;
        }

        public void DeleteWaitPoint(int i, int j)
        {
            TrafficNpcWaitPoint npcWaitPoint = waitPointMaps[i].NpcWaitPoints[j];
            GameObject.DestroyImmediate(npcWaitPoint.gameObject);
            waitPointMaps[i].NpcWaitPoints.RemoveAt(j);

            for (int k = 0; k <  waitPointMaps[i].NpcWaitPoints.Count; k++)
            {
                waitPointMaps[i].NpcWaitPoints[k].transform.name = k.ToString();
            }
        }

        public void RemoveAllWaitPoint(int i)
        {
            if (waitPointMaps[i].NpcWaitPoints==null)
            {
                return;
            }
            
            foreach (var npcWaitPoint in waitPointMaps[i].NpcWaitPoints)
            {
                GameObject.DestroyImmediate(npcWaitPoint.gameObject);
            }
            
            waitPointMaps[i].NpcWaitPoints.Clear();
        }

        public void OnSaved()
        {
            OnValidate();
        }
        
        private void OnValidate()
        {
            if (waitPointMaps!=null && waitPointMaps.Count > 0)
            {
                if (waitPointMaps[0].WayPoint!=null)
                {
                    foreach (var wayPoint in waitPointMaps[0].WayPoint.WayPath.WayPoints)
                    {
                        wayPoint.TrafficLight = null;
                    }
                }

                foreach (var pointMap in waitPointMaps)
                {
                    if (pointMap.WayPoint)
                    {
                        pointMap.WayPathID = pointMap.WayPoint.WayPath.WayID;
                        pointMap.PointIndex = pointMap.WayPoint.Index;
                        pointMap.WayPoint.TrafficLight = this;
                    }
                }
            }


            if (innerPointMaps!=null && innerPointMaps.Count > 0)
            {
                foreach (var pointMap in innerPointMaps)
                {
                    if (pointMap.WayPoint)
                    {
                        pointMap.WayPathID = pointMap.WayPoint.WayPath.WayID;
                        pointMap.PointIndex = pointMap.WayPoint.Index;
                    }
                }
            }
            
        }

        private void OnDrawGizmos()
        {
            // if (waitPointMaps != null && waitPointMaps.Count > 0)
            // {
            //     foreach (var pointMap in waitPointMaps)
            //     {
            //         if (pointMap.WayPoint && pointMap.NpcWaitPoints!=null)
            //         {
            //             foreach (var trafficNpcWaitPoint in pointMap.NpcWaitPoints)
            //             {
            //                 Gizmos.color = Color.yellow;
            //                 Gizmos.DrawLine(trafficNpcWaitPoint.transform.position + Vector3.up * 0.5f,pointMap.WayPoint.transform.position + Vector3.up * 0.5f);
            //             }
            //         }
            //     }
            // }
            //
            // if (LightStatus == TrafficLightStatus.Green)
            // {
            //     Gizmos.color = Color.green;
            // }
            // else
            // {
            //     Gizmos.color = Color.red;
            // }
            //
            // Gizmos.DrawSphere(transform.position + Vector3.up * 12,2f);
            //
            // Gizmos.color = Color.grey;
            //
            // if (colliderCounter.CounterBoxCollider)
            // {
            //     Gizmos.DrawCube(colliderCounter.transform.position + colliderCounter.CounterBoxCollider.center,new Vector3(5,5,5));
            // }
            
        }

#endif

    }

}


